/* 
 * File:   main.c
 *
 * Copyright (C) 2013 Robert Antoni Buj Gelonch <rbuj@uoc.edu>
 * Copyright (C) 2013 David Megias Jimenez <dmegias@uoc.edu>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef FCY
#define FCY 40000000UL
#endif

#include <stdio.h>
#include <stdlib.h>
#include <p33Fxxxx.h>
#include <libpic30.h>

_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);
_FWDT(FWDTEN_OFF);

int main(int argc, char** argv) {
    // Configure PLL prescaller, PLL postscaller. PLL divisor
    PLLFBD = 38; // M = 40
    CLKDIVbits.PLLPOST = 0; // N2=2
    CLKDIVbits.PLLPRE = 0; // N1=2

    // Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0b011)
    __builtin_write_OSCCONH(0x03);
    __builtin_write_OSCCONL(0x01);

    // Wait for Clock switch to occur
    while (OSCCONbits.COSC != 0b011);

    // Wait for PLL to lock
    while (OSCCONbits.LOCK != 1) {
    };
    
    /* set LEDs (D3-D10/RA0-RA7) drive state low */
    LATA = 0xFF00;
    /* set LED pins (D3-D10/RA0-RA7) as outputs */
    TRISA = 0xFF00;

    while(1) {
        LATAbits.LATA0 = 0; // RA0
        LATAbits.LATA1 = 0; // RA1
        __delay32(40000UL); // 1ms delay
        LATAbits.LATA1 = 1; // RA1
        __delay32(40000UL); // 1ms delay
        LATAbits.LATA1 = 0; // RA0
        LATAbits.LATA0 = 1; // RA1
        __delay_ms(1UL);    // 1ms delay
        LATAbits.LATA1 = 1; // RA1
        __delay_us(1000UL); // 1ms delay
    }
    return (EXIT_SUCCESS);
}
